/**
 * 自动引入模板，在原有 sw-precache 插件默认模板基础上做的二次开发
 *
 * 因为是自定导入的模板，项目一旦生成，不支持随 sw-precache 的版本自动升级。
 * 可以到 Lavas 官网下载 basic 模板内获取最新模板进行替换
 *
 */

/* eslint-disable */

'use strict';

var precacheConfig = [["/blog/2020/11/13/hello-world/index.html","f6c89afca0d569cca5346b7ac326611a"],["/blog/2020/11/13/你好/index.html","e3dc138e16e92cb1895460d988732b55"],["/blog/2020/11/15/《图解HTTP》读书笔记（一）/index.html","2638c1095ff0ae61660587028db2385c"],["/blog/2020/11/15/《图解HTTP》读书笔记（三）/index.html","7adbca9dbbf527826ae703fee32ffb1b"],["/blog/2020/11/15/《图解HTTP》读书笔记（二）/index.html","8d80ce067afb7e8864f2960073027595"],["/blog/2020/11/16/Vue源码之深入双向数据绑定/index.html","87b0c7a20ba8f91e43452ebf0b63d630"],["/blog/2020/11/16/表单验证，为避免全局污染写法/index.html","b9b0ca2ffe6194422851a08ee5cb12ff"],["/blog/2020/11/18/《图解HTTP》读书笔记（四）/index.html","a5b1c9ac4b95bf85f1724daf74f9b84e"],["/blog/2020/11/23/《图解HTTP》读书笔记（五）/index.html","684daaff29e2ff58b887a2d36c685944"],["/blog/2020/12/21/点餐页面写法/index.html","ba32f6a416cf2b7da989666065cdc336"],["/blog/2020/12/24/小程序全局配置/index.html","b293c203e0023f6d95cc34bd653321e3"],["/blog/2020/12/24/小程序笔记/index.html","c19246e736cd472b7b8a13e79bcac6c4"],["/blog/2020/12/28/前端面试/index.html","7cc1a98df3b19cae588d4c28e1362fd5"],["/blog/2020/12/29/Webpack/index.html","2fe809aa43db3b7d57a58451004b274c"],["/blog/2020/12/29/理解-JavaScript-中的执行上下文和执行栈/index.html","70e31066f77a39f75ec24d5fd81812ae"],["/blog/2020/12/29/跨域方式/index.html","ed04a037a9bc77d3c19828e9aefc2f5d"],["/blog/2020/12/30/vue中的虚拟DOM和vue的diff算法/index.html","27016c79a467b298ec829123d0f4161f"],["/blog/2020/12/30/vue相关/index.html","74559810d5a31ab977155851cd3ae4eb"],["/blog/2020/12/31/jQuery总结和原生JS/index.html","b8eb8b1e49c41e7899a9a15dc36b713d"],["/blog/2021/01/01/BootStrap/index.html","eba55c0a61cdcf5b8db8e5fd9bc40db5"],["/blog/2021/01/02/axios/index.html","ed26a579bbaa36237ef8f8bc36d7d1a5"],["/blog/2021/01/02/python基础（一）/index.html","324f10fb28125b29cb5d1612ecacc341"],["/blog/2021/01/04/Vuex/index.html","6ef43c283d0516f1a37d9ac65e465034"],["/blog/2021/01/04/python基础（二）/index.html","31f92f7e3c671fd7d07e77272a6fd18f"],["/blog/2021/01/05/python基础（三）/index.html","78d65a495a4449d45b0005fb4d039c20"],["/blog/2021/01/05/python文件操作/index.html","9461aed006f731e82e38f15ba77e77f1"],["/blog/2021/01/05/数据结构与算法（一）/index.html","762e3d715ca6ca6801d527353c45ed88"],["/blog/2021/01/07/python进阶（一）/index.html","f9bb2c536f057173f2f9ade25c869185"],["/blog/2021/01/08/Linux/index.html","5d1f8b30b7542dada99f339313ee5ce1"],["/blog/2021/01/09/伸缩式导航栏/index.html","69ee06a7f03d53e25a1dacec9d038fbc"],["/blog/2021/01/09/动态滑动登录框/index.html","83ad3fd806a7b6d3afbe8e6f28594bb8"],["/blog/2021/01/09/数据库/index.html","c35aef3a456989dd80f3de00010e2ef3"],["/blog/2021/01/10/分层悬浮效果/index.html","650d09a884de9470aa98c189c48755fa"],["/blog/2021/01/10/登录页面UI/index.html","ea3c51a1158a9982066bc0cb31182eee"],["/blog/2021/01/12/Django/index.html","88e4985d3089b23682654f0dfb0dd647"],["/blog/2021/01/12/Vue权威指南/index.html","f6dd3a65ff9f4f3d3266af624984feb6"],["/blog/2021/01/13/Django初/index.html","eb08c64a4e523a47c301fec606f09017"],["/blog/2021/01/14/LeetCode/index.html","8a78bcf2d8343760501c01f35804504e"],["/blog/2021/01/18/Django知识点/index.html","5d9ac8b3e52008e82f752594f65253ad"],["/blog/2021/01/22/全部掌握/index.html","aa52ad5b8431bc1856817cc10ec7c071"],["/blog/Gallery/index.html","84f0c6207b8608fd614c9e79bebdf110"],["/blog/about/index.html","e4cbf410fde7f5f392da8dbad09ebd7c"],["/blog/archives/2020/11/index.html","d2db338dab1bab80844e6d1830fdaebb"],["/blog/archives/2020/12/index.html","cccd8a54c73d0686c2986e117ee2b672"],["/blog/archives/2020/index.html","0fad0ba9e290b24b8f4732aaeaa0926c"],["/blog/archives/2020/page/2/index.html","b0c07c900cc0c659cc503b9b711ac0ba"],["/blog/archives/2021/01/index.html","9b5a010b516f32c13c125f9b70381951"],["/blog/archives/2021/01/page/2/index.html","96aee7aa940ca777597475a17bea82e7"],["/blog/archives/2021/01/page/3/index.html","2307d2abc5685be4b0c3bc680a1098aa"],["/blog/archives/2021/index.html","a691909825e70fbb5a5ded1b0d09219a"],["/blog/archives/2021/page/2/index.html","c5d6203ddf12c6d91026a34144167453"],["/blog/archives/2021/page/3/index.html","f2551def468c4c93fd412abb669754d7"],["/blog/archives/index.html","c867323be61fa1f432712eed933ecae9"],["/blog/archives/page/2/index.html","1ac41d0e1a82d9f77302faec6ad2fd09"],["/blog/archives/page/3/index.html","675010691237dd859b1dca30571532c1"],["/blog/archives/page/4/index.html","58f07fd62b49c4902a377217577b9f05"],["/blog/assets/algolia/algoliasearch.js","d5d2500bfe8443b42baaefe4996ee532"],["/blog/assets/algolia/algoliasearch.min.js","9c5e51e57e2b1d888950bf4cb5708c49"],["/blog/assets/algolia/algoliasearchLite.js","ce9b0e62645c036a143f639b92e7789f"],["/blog/assets/algolia/algoliasearchLite.min.js","c2d71f042c879659dbc97f8853b62f21"],["/blog/categories/BootStrap/index.html","95495e25c1a464a3702bfe8173449c92"],["/blog/categories/Django/index.html","74a07597142f6353d190fdab318db21c"],["/blog/categories/LeetCode/index.html","6b52c4e89f299da00c5e44934b3197e7"],["/blog/categories/Linux/index.html","7d66f905361ff45d993f1aa95422afe2"],["/blog/categories/Python/index.html","ce9ff4d565eca2ec5e50f6932d44c1b1"],["/blog/categories/Vue/index.html","2d88efdbe9e08cf6e0a5709d7f46fd80"],["/blog/categories/Vue源码/index.html","be37afee9fcc3ac958973a1975eb4847"],["/blog/categories/axios/index.html","ae8c9171eaa8c70f49bdd0f8078e9429"],["/blog/categories/index.html","482fe2dcd95a58466db034d73d7f6baf"],["/blog/categories/jQuery/index.html","6680156aa1bc9416862c79528fa0f3e7"],["/blog/categories/伸缩式导航栏/index.html","953a1faecd91ff51c837ffe14c39912a"],["/blog/categories/分层悬浮效果/index.html","006939aa75a29718445ab735ed49eaf1"],["/blog/categories/前端面试/index.html","003b80504241b860e83c9ae25505954b"],["/blog/categories/动态滑动登录框/index.html","8d2cbbe511786afb5949f9335a1260eb"],["/blog/categories/图解HTTP/index.html","9af501a778fe6fadf0b4462a1dcfccc9"],["/blog/categories/小程序/index.html","1e7c3b40f2025d1993e0f6645607c256"],["/blog/categories/数据库/index.html","e7753a8ed4fafd7f80b3ce1627a04b94"],["/blog/categories/数据结构与算法/index.html","6ade845732619182e7754bf82d56d50d"],["/blog/categories/登录页面UI/index.html","842185ecc304d964be7b8d7283b7fd35"],["/blog/categories/随记/index.html","95a9a0ac3a370b4e9109e999965fa8b1"],["/blog/css/VolantisTags.css","00e86b5f8f0c685af0cd50a0e5c72c14"],["/blog/css/fontAnimation.css","e438cbdce5ff14ae374d19c1e13d491b"],["/blog/css/index.css","a2e40a65f674d532a618bb625ac5ea97"],["/blog/css/var.css","d41d8cd98f00b204e9800998ecf8427e"],["/blog/css/volantis.css","77d4b60548bb8c13f02e01ad3a7cefce"],["/blog/img/404.jpg","4ef3cfb882b6dd4128da4c8745e9a507"],["/blog/img/algolia.svg","88450dd56ea1a00ba772424b30b7d34d"],["/blog/img/avatar.png","13fa9ccf7034c87670272dcf664674d6"],["/blog/img/banner/4.jpg","bbb7c6e21eb3e2349bb74de245cd5165"],["/blog/img/cover/bg0.jpg","ee30e011ce88faf8c3b851199980670c"],["/blog/img/cover/bg1.jpg","edc1b7b3cff143d4a72e647dcd149087"],["/blog/img/cover/bg2.jpg","9c86e0aad383f44c47494e8f8ac45722"],["/blog/img/cover/bg3.jpg","f49cc7a81151fc44d8ff06e448d97b06"],["/blog/img/cover/bg4.jpg","cd5bbc48d9a7d1311a52cd61789d5da1"],["/blog/img/cover/bg5.jpg","7829cd254cf6ebe9589c7313f71a92dd"],["/blog/img/cover/bg6.jpg","4d045c5310006fa790cca0cc4a4dae56"],["/blog/img/cover/bg7.jpg","d954ac62bfe7d52f5032f852dd8f5f77"],["/blog/img/cover/bg8.jpg","eda52d224c67d3759881f128439929c8"],["/blog/img/cover/bg9.jpg","968f68634aa66d4486a50bd153da866a"],["/blog/img/friend_404.gif","68af0be9d22722e74665ef44dd532ba8"],["/blog/img/icp.png","6e26aed5ced63bc60524cc736611d39e"],["/blog/img/loading.gif","4d2059397b4a56d1154d97bcf8e65064"],["/blog/img/timg.gif","8c40ecca2178c1f0735cd20fe90cca91"],["/blog/img/valine_bg.png","d954ac62bfe7d52f5032f852dd8f5f77"],["/blog/img/wechat.jpg","a1ace65452da527510b593db4331331b"],["/blog/index.html","2365c5f30dbb3ed068c7f453377b5282"],["/blog/js/Meting.min.js","ea6dd02e8e86a895d27fa6dcf4da6bf3"],["/blog/js/VolantisTags.js","3d18dd231aba8d8ae6ca554723630b3b"],["/blog/js/classify.js","2ec4725eff203ca3defe053eb5ec65ee"],["/blog/js/fish.js","e3b78e3f100d63ce3b90237eed1eec5c"],["/blog/js/fishes.js","60663a3068107503fda96fcb2ef748db"],["/blog/js/main.js","b382597891e958e71bb7c1099977ec66"],["/blog/js/pikaday.js","eccb6a0d9ffad3f2a67fff53e83ec0cf"],["/blog/js/search/algolia.js","24e286714f775d2a52053e530b2ac199"],["/blog/js/search/local-search.js","e3a22e76d8b457655f619551990316e8"],["/blog/js/third-party/ClickShowText.js","22f4c82da4faed04c79e61fcbbdf675c"],["/blog/js/third-party/activate-power-mode.js","e8455f75769585811cd6b3220787d08e"],["/blog/js/third-party/canvas-nest.js","bb643bd9c2ac59f6ce2a1251b8014624"],["/blog/js/third-party/canvas-ribbon.js","4ca518354a167db9fe0869c0982ff215"],["/blog/js/third-party/click_heart.js","c2420dfec66aa5bad663e6c365a129c8"],["/blog/js/third-party/fireworks.js","080fdfcacffc6828826484645140af50"],["/blog/js/third-party/piao.js","5c8c9ff4bb9bed49e333387a54eae9be"],["/blog/js/tw_cn.js","0dcf46510648b9ff1a8a65d270ba117a"],["/blog/js/utils.js","9fadc7723c6bd679aa69c1c158f65af0"],["/blog/js/volantis.js","176cc4b7e4b28ae27e5faa4d28159966"],["/blog/link/index.html","6c5b9806fdef69923ee303ecdfdd7fb6"],["/blog/live2dw/assets/moc/haruto.2048/texture_00.png","56ff69b411abfc80cb68d0b1267959c5"],["/blog/live2dw/lib/L2Dwidget.0.min.js","32973883fcac0a9ae6cc79c0ea25fda2"],["/blog/live2dw/lib/L2Dwidget.min.js","094cbace49a39548bed64abff5988b05"],["/blog/music/index.html","e9112975a106a1b6c075236a55faf29f"],["/blog/page/2/index.html","8ae6e378c018a4f7907edaa85353ff67"],["/blog/page/3/index.html","df752342f1f1c637e9adf471c70f3896"],["/blog/page/4/index.html","e6281131c21da4efc7284d7ad7eb61f5"],["/blog/photo/index.html","3e41abc50c001ec94fe6ac7b4ba996a3"],["/blog/shuoshuo/index.html","3b045b74864d11151bfa99317222ca43"],["/blog/sw-register.js","35c128bd53741a08e5f4ccb9f015d07c"],["/blog/tags/BootStrap/index.html","8fa649d7105e373ace4a76e8e3f3ba08"],["/blog/tags/Django/index.html","6e955e8dc8ad0db823c958306433248d"],["/blog/tags/LeetCode/index.html","bdaac33f0ba19502b8d8c1e273c22ab1"],["/blog/tags/Linux/index.html","c2eeb69db3a5065d8fa6e5befef69fc5"],["/blog/tags/Python/index.html","c0b8a6eb665e8f8670a19b014007dfc1"],["/blog/tags/Vue/index.html","0ee57321a567fe9e01ae9d9a192d23bf"],["/blog/tags/Vue源码/index.html","4ba33c39c260263519b34dd698dc0223"],["/blog/tags/Webpack/index.html","29f9ca7319fcd271044a02bf6e990b04"],["/blog/tags/axios/index.html","2744daba0444c59f58d8d71d03580afd"],["/blog/tags/index.html","9c0de59d5c656c07a3cc62eea5a98d34"],["/blog/tags/jQuery/index.html","e006ef8d6f36d2cf8cad9d98c8a6a1c2"],["/blog/tags/伸缩式导航栏/index.html","c6eb0679d43e3be67abbc12c0fcfe640"],["/blog/tags/你好/index.html","e99831d21544859071e244c4920087fd"],["/blog/tags/分层悬浮效果/index.html","e18990577d22d24a709a7b14a625dd95"],["/blog/tags/前端/index.html","f52df041afa1d734c315255936a61813"],["/blog/tags/前端面试/index.html","61eabd91222a6b789d6895547619088e"],["/blog/tags/动态滑动登录框/index.html","8756df974aa9d2571a21465b3bd23e8b"],["/blog/tags/图解HTTP/index.html","b5f73e911193267e66cd2f74801cc1c3"],["/blog/tags/小程序/index.html","e26e1418ce965bbdc46bf9cda931575f"],["/blog/tags/数据库/index.html","3f67167732eed2f6c8b0acec356c4e8a"],["/blog/tags/数据结构与算法/index.html","5d524b346150d732f73719f4ba54f32e"],["/blog/tags/登录页面UI/index.html","893011215e8d49b5124c574d17a3606c"],["/blog/tags/随记/index.html","54610c404078b6dbb01e45053aa50bd8"]];
var cacheName = 'sw-precache-v3--' + (self.registration ? self.registration.scope : '');
var firstRegister = 1; // 默认1是首次安装SW， 0是SW更新


var ignoreUrlParametersMatching = [/^utm_/];


var addDirectoryIndex = function (originalUrl, index) {
    var url = new URL(originalUrl);
    if (url.pathname.slice(-1) === '/') {
        url.pathname += index;
    }
    return url.toString();
};

var cleanResponse = function (originalResponse) {
    // 如果没有重定向响应，不需干啥
    if (!originalResponse.redirected) {
        return Promise.resolve(originalResponse);
    }

    // Firefox 50 及以下不知处 Response.body 流, 所以我们需要读取整个body以blob形式返回。
    var bodyPromise = 'body' in originalResponse ?
        Promise.resolve(originalResponse.body) :
        originalResponse.blob();

    return bodyPromise.then(function (body) {
        // new Response() 可同时支持 stream or Blob.
        return new Response(body, {
            headers: originalResponse.headers,
            status: originalResponse.status,
            statusText: originalResponse.statusText
        });
    });
};

var createCacheKey = function (originalUrl, paramName, paramValue,
    dontCacheBustUrlsMatching) {

    // 创建一个新的URL对象，避免影响原始URL
    var url = new URL(originalUrl);

    // 如果 dontCacheBustUrlsMatching 值没有设置，或是没有匹配到，将值拼接到url.serach后
    if (!dontCacheBustUrlsMatching ||
        !(url.pathname.match(dontCacheBustUrlsMatching))) {
        url.search += (url.search ? '&' : '') +
            encodeURIComponent(paramName) + '=' + encodeURIComponent(paramValue);
    }

    return url.toString();
};

var isPathWhitelisted = function (whitelist, absoluteUrlString) {
    // 如果 whitelist 是空数组，则认为全部都在白名单内
    if (whitelist.length === 0) {
        return true;
    }

    // 否则逐个匹配正则匹配并返回
    var path = (new URL(absoluteUrlString)).pathname;
    return whitelist.some(function (whitelistedPathRegex) {
        return path.match(whitelistedPathRegex);
    });
};

var stripIgnoredUrlParameters = function (originalUrl,
    ignoreUrlParametersMatching) {
    var url = new URL(originalUrl);
    // 移除 hash; 查看 https://github.com/GoogleChrome/sw-precache/issues/290
    url.hash = '';

    url.search = url.search.slice(1) // 是否包含 '?'
        .split('&') // 分割成数组 'key=value' 的形式
        .map(function (kv) {
            return kv.split('='); // 分割每个 'key=value' 字符串成 [key, value] 形式
        })
        .filter(function (kv) {
            return ignoreUrlParametersMatching.every(function (ignoredRegex) {
                return !ignoredRegex.test(kv[0]); // 如果 key 没有匹配到任何忽略参数正则，就 Return true
            });
        })
        .map(function (kv) {
            return kv.join('='); // 重新把 [key, value] 格式转换为 'key=value' 字符串
        })
        .join('&'); // 将所有参数 'key=value' 以 '&' 拼接

    return url.toString();
};


var addDirectoryIndex = function (originalUrl, index) {
    var url = new URL(originalUrl);
    if (url.pathname.slice(-1) === '/') {
        url.pathname += index;
    }
    return url.toString();
};

var hashParamName = '_sw-precache';
var urlsToCacheKeys = new Map(
    precacheConfig.map(function (item) {
        var relativeUrl = item[0];
        var hash = item[1];
        var absoluteUrl = new URL(relativeUrl, self.location);
        var cacheKey = createCacheKey(absoluteUrl, hashParamName, hash, false);
        return [absoluteUrl.toString(), cacheKey];
    })
);

function setOfCachedUrls(cache) {
    return cache.keys().then(function (requests) {
        // 如果原cacheName中没有缓存任何收，就默认是首次安装，否则认为是SW更新
        if (requests && requests.length > 0) {
            firstRegister = 0; // SW更新
        }
        return requests.map(function (request) {
            return request.url;
        });
    }).then(function (urls) {
        return new Set(urls);
    });
}

self.addEventListener('install', function (event) {
    event.waitUntil(
        caches.open(cacheName).then(function (cache) {
            return setOfCachedUrls(cache).then(function (cachedUrls) {
                return Promise.all(
                    Array.from(urlsToCacheKeys.values()).map(function (cacheKey) {
                        // 如果缓存中没有匹配到cacheKey，添加进去
                        if (!cachedUrls.has(cacheKey)) {
                            var request = new Request(cacheKey, { credentials: 'same-origin' });
                            return fetch(request).then(function (response) {
                                // 只要返回200才能继续，否则直接抛错
                                if (!response.ok) {
                                    throw new Error('Request for ' + cacheKey + ' returned a ' +
                                        'response with status ' + response.status);
                                }

                                return cleanResponse(response).then(function (responseToCache) {
                                    return cache.put(cacheKey, responseToCache);
                                });
                            });
                        }
                    })
                );
            });
        })
            .then(function () {
            
            // 强制 SW 状态 installing -> activate
            return self.skipWaiting();
            
        })
    );
});

self.addEventListener('activate', function (event) {
    var setOfExpectedUrls = new Set(urlsToCacheKeys.values());

    event.waitUntil(
        caches.open(cacheName).then(function (cache) {
            return cache.keys().then(function (existingRequests) {
                return Promise.all(
                    existingRequests.map(function (existingRequest) {
                        // 删除原缓存中相同键值内容
                        if (!setOfExpectedUrls.has(existingRequest.url)) {
                            return cache.delete(existingRequest);
                        }
                    })
                );
            });
        }).then(function () {
            
            return self.clients.claim();
            
        }).then(function () {
                // 如果是首次安装 SW 时, 不发送更新消息（是否是首次安装，通过指定cacheName 中是否有缓存信息判断）
                // 如果不是首次安装，则是内容有更新，需要通知页面重载更新
                if (!firstRegister) {
                    return self.clients.matchAll()
                        .then(function (clients) {
                            if (clients && clients.length) {
                                clients.forEach(function (client) {
                                    client.postMessage('sw.update');
                                })
                            }
                        })
                }
            })
    );
});



    self.addEventListener('fetch', function (event) {
        if (event.request.method === 'GET') {

            // 是否应该 event.respondWith()，需要我们逐步的判断
            // 而且也方便了后期做特殊的特殊
            var shouldRespond;


            // 首先去除已配置的忽略参数及hash
            // 查看缓存简直中是否包含该请求，包含就将shouldRespond 设为true
            var url = stripIgnoredUrlParameters(event.request.url, ignoreUrlParametersMatching);
            shouldRespond = urlsToCacheKeys.has(url);

            // 如果 shouldRespond 是 false, 我们在url后默认增加 'index.html'
            // (或者是你在配置文件中自行配置的 directoryIndex 参数值)，继续查找缓存列表
            var directoryIndex = 'index.html';
            if (!shouldRespond && directoryIndex) {
                url = addDirectoryIndex(url, directoryIndex);
                shouldRespond = urlsToCacheKeys.has(url);
            }

            // 如果 shouldRespond 仍是 false，检查是否是navigation
            // request， 如果是的话，判断是否能与 navigateFallbackWhitelist 正则列表匹配
            var navigateFallback = '';
            if (!shouldRespond &&
                navigateFallback &&
                (event.request.mode === 'navigate') &&
                isPathWhitelisted([], event.request.url)
            ) {
                url = new URL(navigateFallback, self.location).toString();
                shouldRespond = urlsToCacheKeys.has(url);
            }

            // 如果 shouldRespond 被置为 true
            // 则 event.respondWith()匹配缓存返回结果，匹配不成就直接请求.
            if (shouldRespond) {
                event.respondWith(
                    caches.open(cacheName).then(function (cache) {
                        return cache.match(urlsToCacheKeys.get(url)).then(function (response) {
                            if (response) {
                                return response;
                            }
                            throw Error('The cached response that was expected is missing.');
                        });
                    }).catch(function (e) {
                        // 如果捕获到异常错误，直接返回 fetch() 请求资源
                        console.warn('Couldn\'t serve response for "%s" from cache: %O', event.request.url, e);
                        return fetch(event.request);
                    })
                );
            }
        }
    });









/* eslint-enable */
